using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 事件基类管理器
/// 所有的事件（尤其是UI交互事件都必须用管理器写事件，防止后期游戏复杂度增加维护混乱）
/// 目的：所有的界面与逻辑分离
/// 基类负责所有的事件分发处理逻辑
/// </summary>
//[Header("事件管理器，在当前场景生命周期有效，和ButtonEventManager脚本一起构成由按键触发的事件控制器 的预设体")]
public class EventManager
{

    private static EventManager _ins;
    public static EventManager Ins
    {
        get
        {
            if (_ins == null)
            {
                _ins = new EventManager();
            }
            return _ins;
        }
    }
    /// <summary>
    /// 消息列表，每一个事件对应一个枚举类型的消息，枚举类型设计为泛型，方便每个场景都有单独的事件消息层，防止多人开发冲突
    /// </summary>
    [Header("消息类型列表,请定义不能重复的消息key")]
    public string[] eventMsg;
    /// <summary>
    /// 定义代理方法，接受层，接到消息后的回调函数
    /// 保留第一个消息参数，为了更方便的注册到统一入口函数中，第二个参数是回调函数的参数，可为空
    /// </summary>
    public delegate void EventHandle(object param = null);

    /// <summary>
    /// 定义事件字典，记录所有分发中的事件
    /// 支持一个事件多个目标响应
    /// </summary>
    public Dictionary<string, List<EventHandle>> eventDic = new Dictionary<string, List<EventHandle>>();

    void Awake()
    {
        eventDic = new Dictionary<string, List<EventHandle>>();
        //将事件放入字典中管理
        AddEvent();
    }

    /// <summary>
    /// 注册事件
    /// </summary>
    private void AddEvent()
    {
        if (eventMsg.Length == 0)
        {
            Debug.LogWarning("_EVENTMSG is empty,please define add msg key as a array!!");
        }
        foreach (string Msg in eventMsg)
        {
            AddDelegate(Msg);
        }
    }

    /// <summary>
    /// 将事件放入字典中管理
    /// </summary>
    /// <param name="_eventKey">Event key.</param>
    private void AddDelegate(string Msg)
    {
        if (eventDic.ContainsKey(Msg))
        {
            Debug.Log("这个事件已经存在");
        }
        else
        {
            eventDic.Add(Msg, new List<EventHandle>());
        }
    }

    /// <summary>
    /// 触发一个事件
    /// </summary>
    /// <param name="_eventKey">Event key.</param>
    /// <param name="param">Parameter.</param>
    public void TriggerEvent(string Msg, object param = null)
    {
        if (eventDic.ContainsKey(Msg))
        {
            foreach (EventHandle handle in eventDic[Msg])
            {
                handle(param);
            }
        }
        else
        {
            Debug.LogError(Msg + " is undefine from function: _EventBaseManager::_TriigerEvent");
        }
    }
    /// <summary>
    /// 事件绑定
    /// 事件的接收层要调用这个方法，当然也可以使用下面的批量绑定方法，不需要每一个事件写一个函数
    /// </summary>
    public void AttachEvent(string Msg, EventHandle eventHandle)
    {
        if (!eventDic.ContainsKey(Msg))
        {
            eventDic.Add(Msg, new List<EventHandle>());
        }

        eventDic[Msg].Add(eventHandle);
    }
    /// <summary>
    /// 批量导入，所有的事件处理函数入口是唯一的
    /// </summary>
    /// <param name="eventHandle">Event handle.</param>
    public void BatchAttachEvent(EventHandle eventHandle)
    {
        foreach (string Msg in eventMsg)
        {
            AttachEvent(Msg, eventHandle);
        }
    }
    /// <summary>
    /// 去除事件绑定
    /// </summary>
    public void DetachEvent(string Msg, EventHandle eventHandle)
    {
        if (eventDic.ContainsKey(Msg))
        {
            eventDic[Msg].Remove(eventHandle);
        }
        else
        {
            Debug.LogError(Msg + " is undefine from function: _EventBaseManager::_DetachEvent");
        }
    }

    /// <summary>
    /// 销毁管理器，当用代码（单例模式）控制事件分发的时候，结束使用请销毁（因为它不会自动销毁）
    /// </summary>
    public void Destroy()
    {
        // MonoBehaviour.Destroy(this.gameObject);
    }
}
